package com.example.interceptmybatis.intercept;

import com.example.interceptmybatis.annotation.Join;
import com.example.interceptmybatis.entity.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.util.Properties;

@Intercepts({
        @Signature(
                type =  ParameterHandler.class,
                method = "setParameters",
                args = {PreparedStatement.class}
        )
})
@Slf4j
@AllArgsConstructor
@Component
public class MyIntercept implements Interceptor {
    /**
     * 拦截要执行的代理方法
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //返回Mysql的执行结果
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        if(target instanceof ParameterHandler parameterHandler){
            Object parameterObject = parameterHandler.getParameterObject();
            if(parameterObject instanceof BaseEntity){
                addKey(parameterObject);
            }
        }
        return target;
    }

    private Object addKey(Object parameterObject){
        log.info("addKey{}",parameterObject);
        Field[] declaredFields = parameterObject.getClass().getDeclaredFields();
        for (Field field : declaredFields){
            Join join = field.getAnnotation(Join.class);
            if(join!= null){
                field.setAccessible(true);
                try {
                    field.set(parameterObject,field.get(parameterObject)+ join.key());
                } catch (IllegalAccessException e) {

                    throw new RuntimeException(e);
                }
            }
        }
        return(Object) parameterObject;
    }

    @Override
    public void setProperties(Properties properties) {
        Interceptor.super.setProperties(properties);
    }
}
